package cloudlean.zuul.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;

/**
 * 处理成功（statusCode == 200）返回的响应
 *
 * Created by eric on 2018/4/11.
 */
@Configuration
public class MdlResponsePostFilter extends ZuulFilter {
    private static Logger logger = LoggerFactory.getLogger(MdlResponsePostFilter.class);

    @Override
    public String filterType() {
        return POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        // statusCode == 200 的时候执行
        RequestContext ctx = RequestContext.getCurrentContext();
        int statusCode = ctx.getResponseStatusCode();
        return statusCode == HttpServletResponse.SC_OK && ctx.getResponseDataStream() != null;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();

        InputStream stream = ctx.getResponseDataStream();
        String oriData;
        try {
            oriData = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
        } catch (IOException e) {
            logger.error("getResponseDataStream fail!", e);
            throw new RuntimeException("getResponseDataStream fail!", e);
        }

        logger.info("request uri:{}, responseData:{}", ctx.getRequest().getRequestURI(), oriData);

        MdlResponseBody mdlResponseBody;
        try {
            Object jsonObj = JSON.parse(oriData);
            if (jsonObj instanceof JSONObject) {
                Map newDataMap = ((JSONObject) jsonObj).toJavaObject(Map.class);
                mdlResponseBody = new MdlResponseBody(ResponseCode.SUCCESS, newDataMap);
            } else if (jsonObj instanceof JSONArray) {
                List<Map> newDataMapList = ((JSONArray) jsonObj).toJavaList(Map.class);
                mdlResponseBody = new MdlResponseBody(ResponseCode.SUCCESS, newDataMapList);
            } else {
                // 其他类型直接作为字符串进行处理
                mdlResponseBody = new MdlResponseBody(ResponseCode.SUCCESS,"", oriData);
            }
        } catch (JSONException jsonException) {
            // 如果oriData是一个非数字类型的字符串，且不符合json格式，则直接当字符串进行处理
            mdlResponseBody = new MdlResponseBody(ResponseCode.SUCCESS,"", oriData);
        }

        ctx.setResponseBody(JSON.toJSONString(mdlResponseBody));

        return null;
    }
}
